package com.handpay.zztong.hp.swiper.ic;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Vector;

import android.text.TextUtils;

import com.handpay.zztong.hp.log.HPLog;

public class UPcardUtil
{
	// 主密钥（0测试�?生产�?
	final static String		mainKey[]	= { "11111111111111111111111111111111",
			"0D4A16CDA28934B30EF807684C756808" };
	private static byte[]	key13s;				// 普�?密钥
	private static byte[]	key14s;				// PIN密钥
	private static byte[]	key15s;				// MAC密钥
	private static byte[]	key16s;				// 磁道密钥
													
	/**
	 * 密钥给数据加�?
	 * 
	 * @param key
	 * @param data
	 * @return
	 * @throws Exception
	 */
	private static byte[] clacEncrptKey(byte[] key, byte[] data)
			throws Exception
	{
		if (key == null)
		{
			throw new Exception("main bytes is null.");
		}
		if (key.length == 8)
		{
			return Secure.encodeDES(key, data, Secure.AlgorithmDESNo);
		}
		if (key.length > 8)
		{
			return Secure.encode3DES(key, data, Secure.Algorithm3DESNo);
		}
		return null;
	}
	
	private static byte[] clacEncrptKey(String key, String data)
			throws Exception
	{
		return clacEncrptKey(StringUtil.hex2bytes(key),
				StringUtil.hex2bytes(data));
	}
	
	/**
	 * mac计算,数据不为8的�?数，�?���?，将数据8个字节进行异�?, 然后des，再将结果与下一�?个字节异或，�?��到最后；
	 * 
	 * @param key
	 * @param Input
	 * @return
	 * @throws Exception
	 */
	private static byte[] clacMac(byte[] key, byte[] Input) throws Exception
	{
		int length = Input.length;
		int x = length % 8;
		int addLen = 0;
		if (x != 0)
		{
			addLen = 8 - length % 8;
		}
		int pos = 0;
		byte[] data = new byte[length + addLen];
		System.arraycopy(Input, 0, data, 0, length);
		byte[] oper1 = new byte[8];
		System.arraycopy(data, pos, oper1, 0, 8);
		for (int i = 1; i <= data.length / 8; i++)
		{
			byte[] oper2 = new byte[8];
			System.arraycopy(data, pos, oper2, 0, 8);
			byte[] t = null;
			if (i == 1)
			{
				t = StringUtil.bytesXOR(oper1,
						StringUtil.hex2bytes("0000000000000000"));
			}
			else
			{
				t = StringUtil.bytesXOR(oper1, oper2);
			}
			oper1 = clacEncrptKey(key, t);
			pos += 8;
		}
		// �?个长度字�?
		byte[] retBuf = new byte[4];
		System.arraycopy(oper1, 0, retBuf, 0, 4);
		return retBuf;
	}
	
	/**
	 * 主密钥解密传输密�?并截取从1�?7�?做为密钥 key1
	 * 
	 * @param mainKey
	 * @param transmitKey
	 * @return
	 * @throws Exception
	 */
	private static byte[] clacTransmitKey(String mainKey, String transmitKey)
			throws Exception
	{
		byte[] keys = clacDecrptKey(StringUtil.hex2bytes(mainKey), transmitKey);
		byte[] newBytes = new byte[16];
		System.arraycopy(keys, 1, newBytes, 0, 16);
		return newBytes;
	}
	
	/**
	 * 从APDU截取密钥
	 * 
	 * @param apdu
	 * @return
	 */
	private static String getKeyFromAPDU(String apdu)
	{
		if (TextUtils.isEmpty(apdu))
		{
			return null;
		}
		int length = apdu.length();
		if (length < 2)
		{
			return null;
		}
		String cla = apdu.substring(0, 2);
		if (StringUtil.hex2byte(cla) != (byte) 0x84)
		{
			return null;
		}
		if (length < 4)
		{
			return null;
		}
		String ins = apdu.substring(2, 4);
		if (StringUtil.hex2byte(ins) != (byte) 0xF4)
		{
			return null;
		}
		if (length < 6)
		{
			return null;
		}
		String p1 = apdu.substring(4, 6);// 01：安装新密钥�?2：更新已有密�?
		if (p1.compareTo("01") != 0 && p1.compareTo("02") != 0)
		{
			return null;
		}
		if (length < 8)
		{
			return null;
		}
		String p2 = apdu.substring(6, 8);
		if (p2.compareTo("13") != 0 && p2.compareTo("14") != 0
				&& p2.compareTo("15") != 0 && p2.compareTo("16") != 0
				&& p2.compareTo("17") != 0 && p2.compareTo("20") != 0)
		{
			return null;
		}
		if (length < 10)
		{
			return null;
		}
		int lc = StringUtil.hex2byte(apdu.substring(8, 10));
		if (length < 10 + lc)
		{
			return null;
		}
		return apdu.substring(10, 10 + (lc - 4) * 2);
	}
	
	/**
	 * 密钥给数据解�?
	 * 
	 * @param key
	 * @param data
	 * @return
	 * @throws Exception
	 */
	private static byte[] clacDecrptKey(byte[] key, String data)
			throws Exception
	{
		if (key == null)
		{
			throw new Exception("main bytes is null.");
		}
		byte[] dataBytes = StringUtil.hex2bytes(data);
		if (key.length == 8)
		{
			return SecureUtil.decodeDES(key, dataBytes,
					SecureUtil.AlgorithmDESNo);
		}
		if (key.length > 8)
		{
			return SecureUtil.decode3DES(key, dataBytes,
					SecureUtil.Algorithm3DESNo);
		}
		return null;
	}
	
	/**
	 * 解密 13/14/15/16密钥 截取第五到第二十字节 做为key2
	 * 
	 * @param transmitKey
	 * @param macKey
	 * @return
	 * @throws Exception
	 */
	private static byte[] clacWorkKey(byte[] transmitKey, String workKey)
			throws Exception
	{
		byte[] keys = clacDecrptKey(transmitKey, workKey);
		byte[] newBytes = new byte[16];
		System.arraycopy(keys, 4, newBytes, 0, 16);
		return newBytes;
	}
	
	/**
	 * 生成动�?密钥
	 * 
	 * @return
	 */
	private static byte[] getDynamicKeyData()
	{
		try
		{
			byte[] rand = SecureUtil.getRandom(8);
			return rand;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 加密数据补足8的�?�?
	 * 
	 * @param data
	 *            明文数据
	 * @param cover
	 *            补位数�?
	 * @return
	 */
	public static byte[] formatEncData(byte[] data, int cover)
	{
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try
		{
			bos.write(data);
		}
		catch (IOException e)
		{
			return null;
		}
		if (bos.size() % 8 != 0)
		{
			bos.write(0x00);
			while (bos.size() % 8 != 0)
			{
				bos.write(cover);
			}
		}
		return bos.toByteArray();
	}
	
	/**
	 * 组织MAC明文
	 * 
	 * @param elements
	 * @return
	 */
	public static String macBlock(Vector<String> elements)
	{
		String mac_block = "";
		if (elements == null)
		{
			return mac_block;
		}
		int size = elements.size();
		for (int i = 0; i < size; i++)
		{
			String e = elements.elementAt(i);
			mac_block += e;
			if (i < size - 1)
			{
				mac_block += " ";
			}
		}
		mac_block = StringUtil.compressRepeatChar(mac_block, ' ');
		return mac_block;
	}
	
	/**
	 * 装载密钥
	 * 
	 * @param apduKey20
	 * @param apduKey13
	 * @param apduKey14
	 * @param apduKey15
	 * @param apduKey16
	 * @return
	 */
	public static boolean loadKeys(boolean isTest, String apduKey20,
			String apduKey13, String apduKey14, String apduKey15,
			String apduKey16)
	{
		try
		{
			String key13 = getKeyFromAPDU(apduKey13);
			String key14 = getKeyFromAPDU(apduKey14);
			String key15 = getKeyFromAPDU(apduKey15);
			String key16 = getKeyFromAPDU(apduKey16);
			String key20 = getKeyFromAPDU(apduKey20);
			
			HPLog.e("key13",key13);
			HPLog.e("key14",key14);
			HPLog.e("key15",key15);
			HPLog.e("key16",key16);
			HPLog.e("key20",key20);
			
			byte[] key1 = clacTransmitKey(mainKey[isTest ? 0 : 1], key20);
			key13s = clacWorkKey(key1, key13);
			key14s = clacWorkKey(key1, key14);
			key15s = clacWorkKey(key1, key15);
			key16s = clacWorkKey(key1, key16);
			return true;
		}
		catch (Exception e)
		{
			return false;
		}
	}
	
	/**
	 * 加密交易报文数据
	 * 
	 * @param data
	 * @return
	 */
	public static LinkedHashMap<Integer, String> encryptData(LinkedHashMap<Integer, String> map)
	{
		if (map == null || map.isEmpty())
		{
			return null;
		}
		// 获取交易时间
		String time = map.get(4);
		if (TextUtils.isEmpty(time))
		{
			return null;
		}
		try
		{
			// 初始化密�?
			byte[] key13 = clacEncrptKey(key13s,
					StringUtil.hex2bytes(time + "80"));
			byte[] key14 = clacEncrptKey(key14s,
					StringUtil.hex2bytes(time + "80"));
			byte[] key15 = clacEncrptKey(key15s,
					StringUtil.hex2bytes(time + "80"));
			byte[] dynamicKeyData = getDynamicKeyData();
			byte[] tempKey = clacEncrptKey(key16s,
					StringUtil.hex2bytes(time + "80"));
			byte[] key16 = clacEncrptKey(tempKey, dynamicKeyData);
			
			// 加密数据
			// 1:// 支付应用名称cupMobile:application
			// 2:// 版本号cupMobile:version
			// 3:// 交易类型cupMobile.transaction:type
			// (MAC)4:// 交易提交时间cupMobile.transaction.submitTime
			// (13,MAC)5:// 商户代码cupMobile.transaction.merchant:id
			// 6:// 商户名称cupMobile.transaction.merchant:name
			// 7:// 商户国家代码cupMobile.transaction.merchant:country
			// (13,MAC)8:// 子商�?终端代码cupMobile.transaction.terminal:id
			// (13,MAC)9:// 订单号cupMobile.transaction.order:id
			// (MAC)10:// 清算日期cupMobile.transaction.settleDate
			// (13,MAC)11:// 交易金额cupMobile.transaction.transAmount
			// (13,MAC)12:// 交易币种cupMobile.transaction.transAmount:currency
			// (13,MAC)13:// 扣账金额cupMobile.transaction.billAmount
			// (13,MAC)14:// 扣账币种cupMobile.transaction.billAmount:currency
			// (13,MAC)15:// 扣账汇率cupMobile.transaction.billAmount:convertRate
			// (13,MAC)16:// 账户1cupMobile.transaction.accountNumber1
			// (14)17:// 个人身份标识码cupMobile.transaction.pin
			// (MAC)20:// 原始交易提交时间cupMobile.transaction.origSubmitTime
			// (16,MAC)25:// 磁道2数据cupMobile.transaction.track2Data
			// (16,MAC)26:// 磁道3数据cupMobile.transaction.track3Data
			// 27:// 持卡人身份信息cupMobile.transaction.cardholderIdInfo
			// (MAC)28:// 终端芯片序列号cupMobile.transaction.cardSerialNumber
			// 29:// CMSP保留使用cupMobile.transaction.cmspReserved
			// 30:// 账户余额cupMobile.transaction.accountBalance
			// 31:// 账户余额币种cupMobile.transaction.accountBalance:currency
			// 32:// 电子钱包数据cupMobile.transaction.upCashData
			// (13,MAC)33:// 帐户2cupMobile.transaction.accountNumber2
			// (13,MAC)34:// 卡有效期cupMobile.transaction.expireDate
			// 35:// 服务信息cupMobile.transaction.serviceInfo
			// 36:// 动�?密钥数据cupMobile.transaction.dynamicKeyData
			// 37:// 安全载体类型cupMobile.transaction.securityChipTp
			// 38:// SP代码cupMobile.transaction.spId
			// (MAC)39:// 卡片序列号cupMobile.transaction.ICNumber
			// 40:// 系统支持方cupMobile.transaction.SysProvide
			// 41:// 原交易流水号cupMobile.transaction.OrgTransSerNo
			// 42:// 信用卡账户余额cupMobile.transaction.creditAcctBal
			// 43:// 信用卡账户余额币种cupMobile.transaction.creditAcctBal:currency
			// (MAC)251:// 借贷记应用数据cupMobile.transaction.DCData
			// (MAC)252:// 商户摘要数据cupMobile.merchantAuthentication.digest
			// 253:// 商户数字签名cupMobile.merchantAuthentication.signature
			// 254:// 发�?方数字签名cupMobile.senderSignature
			// 255:// 报文鉴别码cupMobile.mac
			
			LinkedHashMap<Integer, String> data = new LinkedHashMap<Integer, String>();
			Vector<String> macElements = new Vector<String>();
			byte[] datas = null;
			for (Integer key : map.keySet())
			{
				String value = map.get(key);
				if (TextUtils.isEmpty(value))
				{
					return null;
				}
				HPLog.i("encryptData",key + " : " + value);
				switch (key)
				{
					case 4:// (MAC)交易提交时间cupMobile.transaction.submitTime
					case 10:// (MAC)清算日期cupMobile.transaction.settleDate
					case 20:// (MAC)原始交易提交时间cupMobile.transaction.origSubmitTime
					case 28:// (MAC)终端芯片序列号cupMobile.transaction.cardSerialNumber
					case 39:// (MAC)卡片序列号cupMobile.transaction.ICNumber
					case 251:// (MAC)借贷记应用数据cupMobile.transaction.DCData
					case 252:// (MAC)商户摘要数据cupMobile.merchantAuthentication.digest
						macElements.addElement(value);
						break;
					case 16:// (13,MAC)账户1cupMobile.transaction.accountNumber1
					case 33:// (13,MAC)帐户2cupMobile.transaction.accountNumber2
						value = StringUtil.string2Hex(value);
					case 5:// (13,MAC)商户代码cupMobile.transaction.merchant:id
					case 8:// (13,MAC)子商�?终端代码cupMobile.transaction.terminal:id
					case 9:// (13,MAC)订单号cupMobile.transaction.order:id
					case 11:// (13,MAC)交易金额cupMobile.transaction.transAmount
					case 12:// (13,MAC)交易币种cupMobile.transaction.transAmount:currency
					case 13:// (13,MAC)扣账金额cupMobile.transaction.billAmount
					case 14:// (13,MAC)扣账币种cupMobile.transaction.billAmount:currency
					case 15:// (13,MAC)扣账汇率cupMobile.transaction.billAmount:convertRate
					case 34:// (13,MAC)卡有效期cupMobile.transaction.expireDate
						datas = formatEncData(StringUtil.hex2bytes(value), 0x00);
						value = StringUtil
								.byte2hex(clacEncrptKey(key13, datas));
						macElements.addElement(value);
						break;
					case 17:// (14)个人身份标识码cupMobile.transaction.pin
						if (value.length() != 6)
						{
							return null;
						}
						value = "0" + value.length() + value + "FFFFFFFF";
//						while(value.length() % 8 != 0)
//						{
//							value += "FF";
//						}
						datas = StringUtil.hex2bytes(value);
						value = StringUtil
								.byte2hex(clacEncrptKey(key14, datas));
						break;
					case 25:// (16,MAC)磁道2数据cupMobile.transaction.track2Data
						String trackLength = String.valueOf(value.length());
						// 截取�?字节整数倍数�?6221438860002219934d491212031011，做加密源数�?
						String trackEnd = value.substring(value.length()
								- value.length() % 8);
						value = value.substring(0,
								value.length() - value.length() % 8);
						datas = formatEncData(StringUtil.hex2bytes(value), 0xFF);
						// 计算磁道加密过程密钥：a,
						// 16号密�?90d2921374d1f08c242b98ae8a5d320+8字节分散因子2013090215234580〉�?3Des计算=
						// 04f2015f8e62e6db (密钥tempKey,)
						// 临时密钥04f2015f8e62e6db(tempKey)+8字节随机�?
						value = StringUtil.byte2hex(clacEncrptKey(key16, datas));
						value = trackLength + value + trackEnd;
						while (value.length() < 40)
						{
							value += "F";
						}
						macElements.addElement(value);
						break;
					case 26:// (16,MAC)磁道3数据cupMobile.transaction.track3Data
						continue;
				}
				data.put(key, value);
			}
			//计算MAC
			String macBlock = macBlock(macElements);
			HPLog.e("macBlock",macBlock);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			bos.write(String.valueOf(macBlock.toCharArray()).getBytes());
			bos.write(0x80);
			while (bos.size() % 8 != 0)
			{
				bos.write(0x00);
			}
			bos.write(0x80);
			for(int i = 0;i < 7;i ++)
			{
				bos.write(0x00);
			}
			byte[] macPlainBytes = bos.toByteArray();			
			byte[] macBytes = clacMac(key15, macPlainBytes);
			String mac = StringUtil.byte2hex(macBytes);
			data.put(255, mac);
			//36:// 动�?密钥数据cupMobile.transaction.dynamicKeyData
			data.put(36, StringUtil.byte2hex(dynamicKeyData));
			return data;
		}
		catch (Exception e)
		{
			return null;
		}
	}
	
	public static void respBalanceEnquiry(String xml)
	{
		UPCardsTransactionResult utr = new UPCardsTransactionResult();
		utr.receive(xml.getBytes());
		LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
		for (int i = 1; i <= 255; i++)
		{
			String value = utr.getElementValue(i);
			if(TextUtils.isEmpty(value))
			{
				continue;
			}
			map.put(i,value);
		}
		map = decryptData(map);
		for (Integer key : map.keySet())
		{
			String value = map.get(key);
			HPLog.i("decryptData",key + " : " + value);
		}
	}
	
	/**
	 * 解密交易报文数据
	 * @param map
	 * @return
	 */
	public static LinkedHashMap<Integer, String> decryptData(LinkedHashMap<Integer, String> map)
	{
		if (map == null || map.isEmpty())
		{
			return null;
		}
		// 获取交易时间
		String time = map.get(4);
		if (TextUtils.isEmpty(time))
		{
			return null;
		}
		try
		{
			// 初始化密�?
			byte[] key13 = clacEncrptKey(key13s,
					StringUtil.hex2bytes(time + "80"));
			byte[] key14 = clacEncrptKey(key14s,
					StringUtil.hex2bytes(time + "80"));
			byte[] key15 = clacEncrptKey(key15s,
					StringUtil.hex2bytes(time + "80"));
			String dynamicKeyData = map.get(36);
			if (TextUtils.isEmpty(dynamicKeyData))
			{
				return null;
			}
//			byte[] dynamicKeyData = getDynamicKeyData();
			byte[] tempKey = clacEncrptKey(key16s,
					StringUtil.hex2bytes(time + "80"));
			byte[] key16 = clacEncrptKey(tempKey, StringUtil.hex2bytes(dynamicKeyData));
			
			// 加密数据
			// 1:// 支付应用名称cupMobile:application
			// 2:// 版本号cupMobile:version
			// 3:// 交易类型cupMobile.transaction:type
			// (MAC)4:// 交易提交时间cupMobile.transaction.submitTime
			// (13,MAC)5:// 商户代码cupMobile.transaction.merchant:id
			// 6:// 商户名称cupMobile.transaction.merchant:name
			// 7:// 商户国家代码cupMobile.transaction.merchant:country
			// (13,MAC)8:// 子商�?终端代码cupMobile.transaction.terminal:id
			// (13,MAC)9:// 订单号cupMobile.transaction.order:id
			// (MAC)10:// 清算日期cupMobile.transaction.settleDate
			// (13,MAC)11:// 交易金额cupMobile.transaction.transAmount
			// (13,MAC)12:// 交易币种cupMobile.transaction.transAmount:currency
			// (13,MAC)13:// 扣账金额cupMobile.transaction.billAmount
			// (13,MAC)14:// 扣账币种cupMobile.transaction.billAmount:currency
			// (13,MAC)15:// 扣账汇率cupMobile.transaction.billAmount:convertRate
			// (13,MAC)16:// 账户1cupMobile.transaction.accountNumber1
			// (14)17:// 个人身份标识码cupMobile.transaction.pin
			// (MAC)20:// 原始交易提交时间cupMobile.transaction.origSubmitTime
			// (16,MAC)25:// 磁道2数据cupMobile.transaction.track2Data
			// (16,MAC)26:// 磁道3数据cupMobile.transaction.track3Data
			// 27:// 持卡人身份信息cupMobile.transaction.cardholderIdInfo
			// (MAC)28:// 终端芯片序列号cupMobile.transaction.cardSerialNumber
			// 29:// CMSP保留使用cupMobile.transaction.cmspReserved
			// 30:// 账户余额cupMobile.transaction.accountBalance
			// 31:// 账户余额币种cupMobile.transaction.accountBalance:currency
			// 32:// 电子钱包数据cupMobile.transaction.upCashData
			// (13,MAC)33:// 帐户2cupMobile.transaction.accountNumber2
			// (13,MAC)34:// 卡有效期cupMobile.transaction.expireDate
			// 35:// 服务信息cupMobile.transaction.serviceInfo
			// 36:// 动�?密钥数据cupMobile.transaction.dynamicKeyData
			// 37:// 安全载体类型cupMobile.transaction.securityChipTp
			// 38:// SP代码cupMobile.transaction.spId
			// (MAC)39:// 卡片序列号cupMobile.transaction.ICNumber
			// 40:// 系统支持方cupMobile.transaction.SysProvide
			// 41:// 原交易流水号cupMobile.transaction.OrgTransSerNo
			// 42:// 信用卡账户余额cupMobile.transaction.creditAcctBal
			// 43:// 信用卡账户余额币种cupMobile.transaction.creditAcctBal:currency
			// (MAC)251:// 借贷记应用数据cupMobile.transaction.DCData
			// (MAC)252:// 商户摘要数据cupMobile.merchantAuthentication.digest
			// 253:// 商户数字签名cupMobile.merchantAuthentication.signature
			// 254:// 发�?方数字签名cupMobile.senderSignature
			// 255:// 报文鉴别码cupMobile.mac
			
			LinkedHashMap<Integer, String> data = new LinkedHashMap<Integer, String>();
			Vector<String> macElements = new Vector<String>();
			String strLen;
			int intLen;
			for (Integer key : map.keySet())
			{
				String value = map.get(key);
				if (TextUtils.isEmpty(value))
				{
					return null;
				}
				switch (key)
				{
					case 4:// (MAC)交易提交时间cupMobile.transaction.submitTime
					case 10:// (MAC)清算日期cupMobile.transaction.settleDate
					case 20:// (MAC)原始交易提交时间cupMobile.transaction.origSubmitTime
					case 28:// (MAC)终端芯片序列号cupMobile.transaction.cardSerialNumber
					case 39:// (MAC)卡片序列号cupMobile.transaction.ICNumber
					case 251:// (MAC)借贷记应用数据cupMobile.transaction.DCData
					case 252:// (MAC)商户摘要数据cupMobile.merchantAuthentication.digest
						macElements.addElement(value);
						break;
					case 16:// (13,MAC)账户1cupMobile.transaction.accountNumber1
					case 33:// (13,MAC)帐户2cupMobile.transaction.accountNumber2
						value = StringUtil.byte2hex(clacDecrptKey(key13, value));
						macElements.addElement(value);
						value = StringUtil.hex2String(value);
						for(int i = value.length() - 1;i >= 0;i --)
						{
							String s = value.substring(i,value.length());
							if(TextUtils.isDigitsOnly(s))
							{
								break;
							}
							value = value.substring(0,i);
						}
						break;
					case 5:// (13,MAC)商户代码cupMobile.transaction.merchant:id
					case 8:// (13,MAC)子商�?终端代码cupMobile.transaction.terminal:id
					case 9:// (13,MAC)订单号cupMobile.transaction.order:id
					case 11:// (13,MAC)交易金额cupMobile.transaction.transAmount
					case 12:// (13,MAC)交易币种cupMobile.transaction.transAmount:currency
					case 13:// (13,MAC)扣账金额cupMobile.transaction.billAmount
					case 14:// (13,MAC)扣账币种cupMobile.transaction.billAmount:currency
					case 15:// (13,MAC)扣账汇率cupMobile.transaction.billAmount:convertRate
					case 34:// (13,MAC)卡有效期cupMobile.transaction.expireDate
						value = StringUtil
								.byte2hex(clacDecrptKey(key13, value));
						macElements.addElement(value);
						break;
					case 17:// (14)个人身份标识码cupMobile.transaction.pin
						value = StringUtil
								.byte2hex(clacDecrptKey(key14, value));
						strLen = value.substring(0,2);
						intLen = Integer.parseInt(strLen);
						if(value.length() < 2 + intLen)
						{
							return null;
						}
						value = value.substring(2,2 + intLen);
						break;
					case 25:// (16,MAC)磁道2数据cupMobile.transaction.track2Data
						if(value.length() != 40)
						{
							return null;
						}
						if(value.length() < 2)
						{
							return null;
						}
						strLen = value.substring(0,2);
						intLen = Integer.parseInt(strLen);
						if(value.length() < 2 + intLen)
						{
							return null;
						}
						value = value.substring(2,2 + intLen);
						String trackEnd = value.substring(value.length()
								- value.length() % 8);
						value = value.substring(0,
								value.length() - value.length() % 8);
						value = StringUtil.byte2hex(clacDecrptKey(key16, value));
						value += trackEnd;
						macElements.addElement(value);
						break;
					case 26:// (16,MAC)磁道3数据cupMobile.transaction.track3Data
						continue;
				}
				data.put(key, value);
			}
			//计算MAC
			String macBlock = macBlock(macElements);
			HPLog.e("macBlock",macBlock);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			bos.write(String.valueOf(macBlock.toCharArray()).getBytes());
			bos.write(0x80);
			while (bos.size() % 8 != 0)
			{
				bos.write(0x00);
			}
			bos.write(0x80);
			for(int i = 0;i < 7;i ++)
			{
				bos.write(0x00);
			}
			byte[] macPlainBytes = bos.toByteArray();			
			byte[] macBytes = clacMac(key15, macPlainBytes);
			String serverMAC = StringUtil.byte2hex(macBytes);
			String clientMAC = map.get(255);
			HPLog.i("serverMAC",serverMAC);
			HPLog.i("clientMAC",clientMAC);
//			//36:// 动�?密钥数据cupMobile.transaction.dynamicKeyData
//			data.put(36, dynamicKeyData);
			return data;
		}
		catch (Exception e)
		{
			return null;
		}
	}
	
	/**
	 * --判断卡号是否合法
	 * 
	 * @param cardNo
	 * @return
	 */
	public static boolean isLegalCard(String cardNo)
	{
		if(TextUtils.isEmpty(cardNo) || !TextUtils.isDigitsOnly(cardNo))
		{
			return false;
		}
        char[] cCardNo = cardNo.toCharArray();
        boolean allZero = true;
        for(int j = 0; j < cCardNo.length; j++) {
            if ('0' != cCardNo[j]) {
                allZero = false;
                break;
            }
        }
        //全零，不是合法卡�?
        if (allZero) {
            return false;
        }
        for (int pos = 1; pos <= 2; pos++) {
            int count = 0;
            boolean bMulti = true;
            for (int i = cCardNo.length - 1 - pos; i >= 0; i--)
            {
                if (bMulti)
                {
                    int multi = (cCardNo[i] - '0') * 2;
                    if (multi > 9)
                    {
                        multi = multi - 9;
                    }
                    count += multi;
                }
                else
                {
                    count += (cCardNo[i] - '0');
                }
                bMulti = !bMulti;
            }
            int addition = Integer.parseInt(cardNo.substring(cardNo.length() - pos, cardNo.length()));
            if ((count + addition) % 10 == 0) {
                return true;
            }
        }
		return false;
	}

    public static String[] parseCard(String serviceInfo)
    {
//        List<String> arrayList = new LinkedList<String>();
        if (serviceInfo != null && serviceInfo.length() > 4) {
            int length = Integer.parseInt(serviceInfo.substring(4, 6));
            String arraylist[] = new String[length];
            for (int i = 0; i < length; i++) {
                int end = (i + 1) * 20 + 6;
                if (end > serviceInfo.length()) {
                    end = serviceInfo.length();
                }
                arraylist[i] = (serviceInfo.substring(6 + i * 20, end)
                        .trim());
            }
            return arraylist;
        }
        return null;
    }
}
